package me.feng.actors

import java.nio.CharBuffer
import com.lambdaworks.jacks.JacksMapper
import akka.actor.Actor
import me.feng.entity.Event
import me.feng.entity.Message
import me.feng.entity.User
import me.feng.entity.EventType
import me.feng.entity.Letter
import me.feng.messageinbound.MainChart
import scala.collection.mutable.Map
import me.feng.entity.LetterType
import me.feng.entity.MessageType

class UserActor(u: User) extends Actor {

  private val chatMap: Map[String, MainChart] = Map[String, MainChart]()
  
  private val msgCache :Map[String, List[Message[Letter]]] = Map[String,List[Message[Letter]]]()

  def receive = {
    
    case chat: MainChart => {
      
      chat.setUser(u)
      chatMap += (chat.getCid -> chat)
      
      if(!chat.getCid.equals("0")){
        Thread.sleep(1000)
        val msgList = if(msgCache.contains(chat.getCid)) msgCache(chat.getCid) else List()
        if(msgList.size>0){
          msgList.foreach(msg => {
            chat.getWsOutbound().writeTextMessage(CharBuffer.wrap(JacksMapper.writeValueAsString(msg)))
          })
          msgCache.remove(chat.getCid)
        }
      }
      
      chatMap.foreach(p => {
        println("ChatMap: " + p._1+ " -> "+p._2.getUser.id )
      })
    }
    
    case msg: Message[Letter] => {
      
      chatMap.foreach(p => {
        println("ChatMap: " + p._1+ " -> "+p._2.getUser.id )
      })
      
      val uid = msg.result.kind match {
        case LetterType.MAIN => "0"
        case LetterType.USER => {
          if (msg.result.from.id.equals(u.id))  msg.result.cid else  msg.result.from.id
        }
      }
      
     if(chatMap.contains(uid)){
         val chat= chatMap(uid)
         if (chat != null && chat.open)
        	 chat.getWsOutbound().writeTextMessage(CharBuffer.wrap(JacksMapper.writeValueAsString(msg)))
      }else{
        if(msgCache.contains(uid)){
          msgCache(uid) :+= msg
        }else{
          msgCache += (uid -> List(msg))
        }
        val e = new Event(msg.result.from,msg.result.cid,EventType.NEW_SESSION)
        sender ! e
      }
    }

    case e: Event => {
      val msg = new Message(MessageType.EVENT, e)
      e.event match {
        case EventType.CLOSE => {
          chatMap.values.foreach(chat => {
            if (chat != null && chat.open)
              chat.getWsOutbound().writeTextMessage(CharBuffer.wrap(JacksMapper.writeValueAsString(msg)))
          })
        }

        case EventType.LOGIN => {
          val chat = chatMap("0")
          if (chat != null && chat.open)
            chat.getWsOutbound().writeTextMessage(CharBuffer.wrap(JacksMapper.writeValueAsString(msg)))
        }
        
        case EventType.EIXT_SESSION => {
          chatMap -= e.cid
        }
        
        case EventType.NEW_SESSION => {
          val chat = chatMap("0")
          if (chat != null && chat.open)
            chat.getWsOutbound().writeTextMessage(CharBuffer.wrap(JacksMapper.writeValueAsString(msg)))
        }
      }

    }

    case oluser: Map[String, User] => {
      val chat = chatMap("0")
      if (chat != null && chat.open) {
        oluser.foreach {
          case (k, v) => {
            val event = new Event(v,"0", EventType.REFRESH_ONLINE_USERS)
            val msg = new Message(MessageType.EVENT, event)
            chat.getWsOutbound().writeTextMessage(CharBuffer.wrap(JacksMapper.writeValueAsString(msg)))
          }
        }
      }
    }
  }
}